#include "objMeshLoader.h"
#include "dataInModelConstants.h"
#include <vector>
#include <string>
#include <fstream>
#include <sstream>



bool ObjMeshLoader::LoadObjModel( const char* fileName, ObjModel& objModel )
{
	ifstream input( fileName );
	string buffer;

	if( !input.good() )
	{
		input.close();
		return false;
	}

	bool firstTime = true;
	string currentModelElement("");
	istringstream line;
	int formatType = -1;

	//przegladamy linijka po linijce caly plik
	while( getline( input, buffer ) )
	{
		line.clear();
		line.str( buffer );
		string header;
		//cout << buffer;// << endl;
		//line >> header;
		//cout<< "header is: " << header << endl;

		if( buffer.substr( 0, 2 ) == "vn" )
		{
			float x,y,z;
			line >> header >> x >> y >> z;
			objModel.normals.push_back( ObjNormal(x,y,z) );
		}
		else
		if( buffer.substr( 0, 2 ) == "vt" )
		{
			float x,y;
			line >> header >> x >> y;
			objModel.texCoords.push_back( ObjTexCoord(x,y) );
		}
		else
		if( buffer.substr( 0, 1 ) == "v" )
		{
			float x,y,z;
			line >> header >> x >> y >> z;
			objModel.vertices.push_back( ObjVertex(x,y,z) );
		}
		else
		if( buffer.substr( 0, 1 ) == "g" )
		{
			line >> header;
			string partName;

			//pobieramy cala nazwe grupy
			while( line >> partName )
				currentModelElement += partName;

			objModel.modelElements.push_back( ObjModelElement(currentModelElement) );
			//cout << currentModelElement << endl;
			currentModelElement = "";
		}
		else
		if( buffer.substr( 0, 1 ) == "f" )
		{
			line >> header;

			//przy pierwszym parsowaniu polygonu badamy format w jakim podany jest wierzcholek.
			//moze byc to v/vt/vn,  v//vn,   v,   v/vt
			if( firstTime )
			{
				firstTime = false;

				string tmp = buffer.substr( buffer.find(' '), buffer.find(' ', buffer.find(' ') + 1) );
				string::size_type posFront = -1;
				string::size_type posBack = -1;

				posFront = tmp.find( '/' );
				posBack = tmp.rfind( '/' );

				if( posFront == string::npos )
				{
					formatType = 1;
					objModel.dataInModel = V_DATA;
				}
				else
				if( posFront == posBack )
				{
					formatType = 2;
					objModel.dataInModel = V_AND_VT_DATA;
				}
				else
				if( posFront + 1 == posBack )
				{
					formatType = 3;
					objModel.dataInModel = V_AND_VN_DATA;
				}
				else
				{
					formatType = 4;
					objModel.dataInModel = V_AND_VT_AND_VN_DATA;
				}

				//cout << "rfind is:" << buffer.rfind(' ') << "length is:" << buffer.length() << endl;
				//cout<<tmp<<endl;
				//cout<< "format type is " << formatType<<endl;
			}

			int v, vn, vt = -1;
			ObjFace objFace;
			string ithVertex;
			//przegladamy cala linijke, w zmiennej ithVertex mamy kolejne wiercholki w ustalonym formacie

			int i = 0;
			//cout<< "f";
			while( line >> ithVertex )
			{
				//cout<< ithVertex << ",";

				if( formatType == 1 )
				{
					sscanf_s( ithVertex.c_str(), "%d", &v );
					//objFace.vertex.push_back( v );
					objFace.vertex[ i++ ] = v;
				}
				else
				if( formatType == 2 )
				{
					sscanf_s( ithVertex.c_str(), "%d/%d", &v, &vt );
					//objFace.vertex.push_back( v );
					//objFace.texCoord.push_back( vt );
					objFace.vertex[ i ] = v;
					objFace.texCoord[ i++ ] = vt;
				}
				else
				if( formatType == 3 )
				{
					sscanf_s( ithVertex.c_str(), "%d//%d", &v, &vn );
					//objFace.vertex.push_back( v );
					//objFace.normal.push_back( vn );
					objFace.vertex[ i ] = v;
					objFace.normal[ i++ ] = vn;
				}
				else
				if( formatType == 4 )
				{
					sscanf_s( ithVertex.c_str(), "%d/%d/%d", &v, &vt ,&vn );
					//objFace.vertex.push_back( v );
					//objFace.normal.push_back( vn );
					//objFace.texCoord.push_back( vt );
					objFace.vertex[ i ] = v;
					objFace.normal[ i ] = vn;
					objFace.texCoord[ i++ ] = vt;

					//cout << " " << v << "/" << vt << "/" << vn;
				}
			}
			//cout<< endl;

			//sprawdzamy czy dobra ilosc wierzcholkow
			if( i > maxNumberOfVerticesPerFace )
			{
				return false;
			}

			//dadajemy ten fejs do aktualnej grupy
			objModel.numberOfVerticesPerFace = i;
			objModel.modelElements.back().faces.push_back( objFace );
		}
	}

	return true;
}